<?php

namespace WeChatDeveloper\app;

class Wx_return {
    /********************************以下是微信方法【中括号里的数字代表步骤顺序】********************************************/
    private  static $_instance;
    private $array;
    /*
      public function __construct($array) {
          $this->array = $array;
      }

      //默认生成对象 需传入nonce_str，body，order_no，total_fee，openid
      public function getInstance($array)
      {

          if(! (self::$_instance instanceof self) )
          {
              self::$_instance = new self($array);
          }
          return self::$_instance;

      }
  */

    //将json数组转为xml文件【1】
    public function ToXml($data) {
        if (!is_array($data->values) || count($data->values) <= 0) {
            //throw new WxPayException("数组数据异常！");
            echo "数组数据异常！";
        }

        $xml = "<xml>";
        foreach ($data->values as $key => $val) {   //echo "<".$key.">".$val."</".$key.">";
            if (is_numeric($val)) {
                $xml .= "<" . $key . ">" . $val . "</" . $key . ">";
            } else {
                $xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";
                // $xml .= "<" . $key . ">" . $val . "</" . $key . ">";
            }
        }
        $xml .= "</xml>";
        //echo $xml;
        return $xml;
    }

    //设置签名【2】
    public function SetSign($postData) {
        $sign = $this->MakeSign($postData);
        $this->values['sign'] = $sign;
        return $sign;
    }

    //微信支付生成签名1.字典排序。2.加入key。3.md5【2.1】
    public function MakeSign($postData) {
        $post = $postData->values;
        //签名步骤一：按字典序排序参数
        ksort($post);
        $string = $this->ToUrlParams($post);
        //签名步骤二：在string后加入KEY
        $string = $string . "&key=".config('minipay.mch_key');
        //签名步骤三：MD5加密
        $string = md5($string);
        //签名步骤四：所有字符转为大写
        $result = strtoupper($string);
        return $result;
    }

    //自动字符串拼接【2.2】
    public function ToUrlParams($postData) {
        $buff = "";
        foreach ($postData as $k => $v) {
            if ($k != "sign" && $v != "" && !is_array($v)) {
                $buff .= $k . "=" . $v . "&";
            }
        }
        $buff = trim($buff, "&");
        return $buff;
    }

    //微信支付XML文件post方法【2】
    public function postXmlCurl($xml, $url, $useCert = false, $second = 30) {
        file_put_contents( "mini_refund.txt", $xml . PHP_EOL, FILE_APPEND);
        file_put_contents( "mini_refund.txt", $url . PHP_EOL, FILE_APPEND);
        $ch = curl_init();
        //设置超时
        curl_setopt($ch, CURLOPT_TIMEOUT, $second);
        //如果有配置代理这里就设置代理
        if ("0.0.0.0" != "0.0.0.0" && 0 != 0) {
            curl_setopt($ch, CURLOPT_PROXY, "0.0.0.0");
            curl_setopt($ch, CURLOPT_PROXYPORT, 0);
        }
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); //严格校验
        //设置header
        curl_setopt($ch, CURLOPT_HEADER, FALSE);
        //要求结果为字符串且输出到屏幕上
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        if ($useCert == true) {
            //设置证书
            //使用证书：cert 与 key 分别属于两个.pem文件
            curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM');
            curl_setopt($ch, CURLOPT_SSLCERT, config('minipay.ssl_cer'));
            curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM');
            curl_setopt($ch, CURLOPT_SSLKEY, config('minipay.ssl_key'));
        }
        //post提交方式
        curl_setopt($ch, CURLOPT_POST, TRUE);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
        //运行curl
        $data = curl_exec($ch);
        file_put_contents( "mini_refund.txt", "curl结果:" . PHP_EOL, FILE_APPEND);
        file_put_contents( "mini_refund.txt", json_encode($data) . PHP_EOL, FILE_APPEND);
        //返回结果
        if ($data) {
            curl_close($ch);
            return $data;
        } else {
            $error = curl_errno($ch);
            curl_close($ch);
            file_put_contents( "error.txt", "curl出错，错误码:".$error . PHP_EOL, FILE_APPEND);
        }
    }

    //微信支付获取prepay_id接口成功后解析xml文件返回数组格式数据【3】
    //将xml转成数组
    function xmlToArray($xml) {
        //禁止引用外部xml实体
        libxml_disable_entity_loader(true);
        $xmlstring = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA);
        $val = json_decode(json_encode($xmlstring), true);
        return $val;
    }

    //微信支付回调方法-已在调用静态方法array中设置路径【4】
    public function WeixinPayNotify() {
        echo "回调成功";
    }

    /*
     * 需传入nonce_str，order_no，total_fee，notify_url,out_refund_no,refund_fee,refund_desc
     * @function 获取微信支付信息
     * */
    public function WeixinPay($array) {
        //1.所需传送字段
        $appid = config('mini.mini_user_appid'); //公众号appid
        $mch_id = config('minipay.mch_id'); //商户号
        if (  $array['out_trade_no'] == "" || $array['total_fee'] == "") {
            $respData = array('code' => -1, 'message' => 'out_trade_no,total_fee,不能为空');
            echo json_encode($respData);
        }
        $postUrl = "https://api.mch.weixin.qq.com/secapi/pay/refund";
        $postData="";
        $postData->values['appid'] = $appid;
        $postData->values['mch_id'] = $mch_id;
        $postData->values['nonce_str'] = $array['nonce_str']; //随机字符串
        $postData->values['transaction_id'] = $array['transaction_id'];
        $postData->values['out_trade_no'] = $array['out_trade_no']; //要退款的商户订单号
        $postData->values['out_refund_no'] = $array['out_refund_no'];//商户退款单号
        $postData->values['total_fee'] = $array['total_fee']; //订单总金额
        $postData->values['refund_fee'] = $array['refund_fee'];//退款总金额
        $postData->values['refund_desc'] = $array['refund_desc'];//退款原因
        //$postData->values['notify_url'] = $array['notify_url'];//回调地址,退款结果通知url-不是必要的。
        file_put_contents( "mini_refund.txt",'发送数据:'.PHP_EOL.PHP_EOL, FILE_APPEND);
        file_put_contents( "mini_refund.txt",json_encode($postData).PHP_EOL.PHP_EOL, FILE_APPEND);
        //2.统一支付签名
        $postData->values['sign'] = $this->SetSign($postData);
        $xml = $this->ToXml($postData);
        $timeOut = 6;
        $response = $this->postXmlCurl($xml, $postUrl, true, $timeOut);
        file_put_contents( "mini_refund.txt",'微信回调结果:'.PHP_EOL.PHP_EOL, FILE_APPEND);
        file_put_contents( "mini_refund.txt",$response.PHP_EOL.PHP_EOL, FILE_APPEND);
        file_put_contents( "mini_refund.txt",json_encode($response).PHP_EOL.PHP_EOL, FILE_APPEND);
        //3.统一支付回调prepay_id
        $result = $this->xmlToArray($response);
        file_put_contents( "mini_refund.txt",'微信回调array结果:'.PHP_EOL.PHP_EOL, FILE_APPEND);
        file_put_contents( "mini_refund.txt",json_encode($response).PHP_EOL.PHP_EOL, FILE_APPEND);
        return $result;
        /*
        if($result['return_code']=='FAIL'){
            return  array("code"=>400,"msg"=>$result['return_msg'],"err"=>$response,"result"=>$result);
        }
        else  return  array("code"=>200,"result"=>$result);
        */
    }
    public function init($array){
        return  $this->WeixinPay($array);
    }
    //测试证书文件是否存在
    public function test_file(){
        echo config('minipay.ssl_key')."</br>";
        echo config('minipay.ssl_cer');
        if(!file_exists(config('minipay.ssl_cer'))){
            echo '不存在';
        }
        else{
            echo '存在';
        }
    }
}